package com.authentication.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

import static com.authentication.common.Constant.GRANTED_SCOPES;

/**
 * oauth2 用于 用户判断是否同意 client 访问 user 信息的过滤器
 */
public class SelectingOauth2ScopeFilter extends OncePerRequestFilter {

    public static final String OAUTH_2_AUTHORIZATION_DECISION = "oauth2AuthorizationDecision";
    private final RequestCache requestCache;

    private final String selectScopeUrl;


    public SelectingOauth2ScopeFilter(RequestCache requestCache, String selectScopeUrl) {
        this.requestCache = requestCache;
        this.selectScopeUrl = selectScopeUrl;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String oauth2AuthorizationDecision = request.getParameter(OAUTH_2_AUTHORIZATION_DECISION);

        if (!"true".equals(oauth2AuthorizationDecision)) {
//            1、第一次请求没有用户的 授权决定信息(同意授权/拒绝授权),要求获取用户的授权决定
//            临时保存用户的授权请求
            requestCache.saveRequest(request, response);
            response.sendRedirect(selectScopeUrl);
            return;
        }

        String[] grantedScopes = request.getParameterValues(GRANTED_SCOPES);
        if (grantedScopes.length == 0) {
            //TODO  拒绝访问
            return;
        }


        SavedRequest savedRequest = requestCache.getRequest(request, response);

        if (savedRequest == null) {
//          3、用户请求包含 授权决定信息(同意授权/拒绝授权) 和 授权请求 二者的信息
//          放行
            filterChain.doFilter(request, response);
            return;
        }

        /*
         * 用户填写 授权决定信息(同意授权/拒绝授权) 后第二次访问
         * 从请求缓存中取出原本的授权请求
         * */
        requestCache.removeRequest(request, response);


        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add(OAUTH_2_AUTHORIZATION_DECISION, "true");
        params.addAll(GRANTED_SCOPES, Arrays.asList(grantedScopes));

        /*
         * 把用户的 授权决定信息(同意授权/拒绝授权) 拼接到 原本的 授权请求中
         * */
        String redirectUrl = UriComponentsBuilder.fromHttpUrl(savedRequest.getRedirectUrl())
                .queryParams(params)
                .build().toUriString();

        response.sendRedirect(redirectUrl);


    }
}
